import {_decorator, CCBoolean, CCInteger, Component, EventTouch, Node, UITransform, Vec3, view} from "cc";
import {JoyStickTouchType} from "db://assets/scripts/ui/joystick/JoyStickTouchType";
import {JoyStickDirectionType} from "db://assets/scripts/ui/joystick/JoyStickDirectionType";
import {AudioManager} from "db://assets/scripts/common/AudioManager";
import {GameManager} from "db://assets/scripts/game/GameManager";
import {EventManager} from "db://assets/scripts/common/EventManager";
import {PlayerDataManager} from "db://assets/scripts/common/PlayerDataManager";
import {EventType} from "db://assets/scripts/common/EventType";
import {PlayerActionEnum} from "db://assets/scripts/game/role/player/PlayerActionEnum";
import {GameState} from "db://assets/scripts/game/GameState";

const {ccclass, property} = _decorator;

@ccclass("Joystick")
export class Joystick extends Component {
    @property({type: Node, tooltip: "摇杆背景节点"})
    public ndRing: Node;

    @property({type: Node, tooltip: "摇杆节点"})
    public ndDot: Node;

    @property({tooltip: "触摸类型"})
    public touchType: JoyStickTouchType = JoyStickTouchType.DEFAULT;

    @property({tooltip: "方向类型"})
    public directionType: JoyStickDirectionType = JoyStickDirectionType.ALL;

    @property({type: CCBoolean, tooltip: "启动半透明"})
    public isEnableTransparent: boolean = false;

    @property({type: CCBoolean, tooltip: "点击跟随"})
    public isFollowStart: boolean = false;

    @property({type: CCInteger, tooltip: "内圈大小"})
    public innerSize: number = 10;

    @property(Node)
    public ndTip: Node = null!;//第一关文字提示

    public onClickCb: Function = null!;
    public onEndCb: Function = null!;
    public clearFECb: Function = null!;
    public onBeginFECb: Function = null!;
    public onSuccessFECb: Function = null!;
    public isMoving: boolean = false;//是否正在移动

    public get distanceRate() {
        return this._distanceRate;
    }

    public get angle() {
        return this._angle;
    }

    public set angle(v: number) {
        this._angle = v;
    }

    private _angle: number = 0;//当前的角度
    private _oriRingPos: Vec3 = null!;//圆圈初始位置
    private _targetRingPos: Vec3 = new Vec3();//圆圈背景位置
    private _touchStartLocation: Vec3 = new Vec3();//开始触碰位置
    private _touchMoveLocation: Vec3 = new Vec3();//移动触碰位置
    private _touchEndLocation: Vec3 = new Vec3();//结束触碰位置
    private _isOutInnerSize: Boolean = false;//终点拖动的点是否超出按钮圆圈背景
    private _distanceRate: number = 0; //遥感移动距离比
    private _checkInterval: number = 0.04;//每40ms刷新一次
    private _oldAngle: number = 0;//之前的角度
    private _currentTime: number = 0;//当前累积时间
    private _oriDotPos: Vec3 = new Vec3();//中间按钮初始坐标
    private _movePos: Vec3 = new Vec3();//移动坐标
    private _curRingPos_1: Vec3 = new Vec3();//当前圆圈坐标
    private _curRingPos_2: Vec3 = new Vec3();//

    private screenHeight = view.getVisibleSize().height;//屏幕可视范围高度

    start() {
        // Your initialization goes here.

        if (PlayerDataManager.getInstance().getPlayer().floor > 1 && this.ndTip.active) {
            this.ndTip.active = false;
        }
    }

    onEnable() {
        this.node.on(Node.EventType.TOUCH_START, this._touchStartEvent, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);

        // 触摸在圆圈内离开或在圆圈外离开后，摇杆归位，player速度为0
        this.node.on(Node.EventType.TOUCH_END, this._touchEndEvent, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
    }

    onDisable() {
        this.node.off(Node.EventType.TOUCH_START, this._touchStartEvent, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);

        // 触摸在圆圈内离开或在圆圈外离开后，摇杆归位，player速度为0
        this.node.off(Node.EventType.TOUCH_END, this._touchEndEvent, this);
        this.node.off(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);

        //重置
        this.isMoving = false;
        this.ndDot.setPosition(this._oriDotPos);
        if (this._oriRingPos) {
            this.ndRing.setPosition(this._oriRingPos);
        }
    }

    private _touchStartEvent(event: EventTouch) {
        // 记录触摸的世界坐标，给touch move使用
        // this.dot.opacity = 255;
        this._targetRingPos = null!;

        let touch = event.getUILocation();
        this._touchStartLocation.set(touch.x, touch.y, 0);
        let touchPos = this.node.getComponent(UITransform)?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;

        if (!this._oriRingPos) {
            this._oriRingPos = this.ndRing.getPosition().clone();
        }

        // 记录摇杆位置，给touch move使用
        // this._stickPos.set(touchPos);

        this._isOutInnerSize = false;

        if (!this.isFollowStart) {
            touchPos = this.ndRing.getComponent(UITransform)?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;

            //触摸点与圆圈中心的距离
            let distance = touchPos.length();
            let width = this.ndRing.getComponent(UITransform)?.contentSize.width as number;
            //圆圈半径
            let radius = width / 2;

            //手指在圆圈内触摸,控杆跟随触摸点
            if (radius > distance) {
                this.ndDot.setPosition(touchPos);
                this._updateAngle(touchPos);
                return true;
            }
            return false;

        } else {
            //设置遥感可移动范围
            if (this.touchType === JoyStickTouchType.FOLLOW) {
                touchPos.y = touchPos.y >= -this.screenHeight / 6 ? -this.screenHeight / 6 : touchPos.y;
            }

            this.ndRing.setPosition(touchPos);
        }
    }

    private _touchMoveEvent(event: EventTouch) {
        let touch = event.getUILocation();
        this._touchMoveLocation.set(touch.x, touch.y, 0);
        let touchPos = this.ndRing.getComponent(UITransform)?.convertToNodeSpaceAR(this._touchMoveLocation) as Vec3;

        // if (this.touchType === TOUCH_TYPE.FOLLOW) {
        //     let offsetPos = cc.v3(touchPos.x - this._stickPos.x, touchPos.y - this._stickPos.y, 0);
        //     touchPos = offsetPos;
        // }

        let distance = touchPos.length();

        if (distance > this.innerSize) {
            this.isMoving = true;
            this._isOutInnerSize = true;
        } else {
            this._isOutInnerSize = false;
        }

        //有拖动且有角度才视为开始游戏
        if (GameManager.getInstance().gameStateProxy.getGameState() !== GameState.PLAYING && this.isMoving) {
            GameManager.getInstance().gameStateProxy.setGameState(GameState.PLAYING);
            AudioManager.getInstance().resumeAll();
            console.log("TouchMove>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            EventManager.dispatchEvent(EventType.MONSTER_MOVE);

            if (this.ndTip.active) {
                this.ndTip.active = false;
            }

            this._currentTime = this._checkInterval;
        }

        let width = this.ndRing.getComponent(UITransform)?.contentSize.width as number;
        //圆圈半径
        let radius = width / 2;
        let rate = 0;
        // 由于摇杆的postion是以父节点为锚点，所以定位要加上ring和dot当前的位置(stickX,stickY)
        if (radius > distance) {
            rate = Number((distance / radius).toFixed(3));
            this.ndDot.setPosition(touchPos);
        } else if (this.touchType !== JoyStickTouchType.FOLLOW_DOT) {
            rate = 1;
            //控杆永远保持在圈内，并在圈内跟随触摸更新角度
            let radian = Math.atan2(touchPos.y, touchPos.x);

            let x = Math.cos(radian) * radius;
            let y = Math.sin(radian) * radius;
            this._movePos.set(x, y, 0);
            if (this.touchType === JoyStickTouchType.FOLLOW_ALWAYS) {
                this._curRingPos_2.set(touch.x - x, touch.y - y, 0);
                let ringPos = this.node.getComponent(UITransform)?.convertToNodeSpaceAR(this._curRingPos_2) as Vec3;
                this._targetRingPos = ringPos;
            }

            this.ndDot.setPosition(this._movePos);
        } else {
            // 点跟随移动
            this.ndDot.setPosition(touchPos);
        }
        //更新角度
        this._updateAngle(touchPos);
        //更新遥感移动距离百分比
        this._distanceRate = rate;
    }

    private _touchEndEvent(event: EventTouch) {
        if (!this.isMoving) {
            //可以判断为点击
            this.onClickCb && this.onClickCb();
        } else {
            let touch = event.getUILocation();
            this._touchEndLocation.set(touch.x, touch.y, 0);
            let touchPos = this.ndRing.getComponent(UITransform)?.convertToNodeSpaceAR(this._touchEndLocation) as Vec3;
            let isDragToInner = false;
            if (touchPos.length() < this.innerSize) {
                //取消掉
                isDragToInner = true;

                this.onEndCb && this.onEndCb(isDragToInner);

            } else {
                this.onEndCb && this.onEndCb(isDragToInner);
            }
        }

        this.isMoving = false;
        this.ndDot.setPosition(this._oriDotPos);

        if (this.touchType === JoyStickTouchType.FOLLOW
            || this.touchType === JoyStickTouchType.FOLLOW_ALWAYS
            || this.touchType === JoyStickTouchType.FOLLOW_DOT) {
            this._targetRingPos = null!;
            this.ndRing.setPosition(this._oriRingPos);
        }
    }

    private _updateAngle(pos: Vec3) {
        this._angle = Math.round(Math.atan2(pos.y, pos.x) * 180 / Math.PI);
        return this._angle;
    }

    public reset() {
        this.isMoving = false;
        this.ndDot.setPosition(this._oriDotPos);
    }

    update(deltaTime: number) {
        if (GameManager.getInstance().gameStateProxy.getGameState() !== GameState.PLAYING
            || GameManager.getInstance().gameStateProxy.getGameState() === GameState.OVER
            || GameManager.getInstance().gameStateProxy.getGameState() === GameState.PAUSE
            || !GameManager.getInstance().gamePlayerProxy.getPlayerController()) {
            return;
        }

        //设置终终点按钮位置
        if (this._targetRingPos) {
            this._curRingPos_1.set(0, 0, 0);
            Vec3.lerp(this._curRingPos_1, this.ndRing.position, this._targetRingPos, 20 * deltaTime);

            this.ndRing.setPosition(this._curRingPos_1);
        }

        this._currentTime += deltaTime;

        if (this._currentTime >= this._checkInterval) {
            this._currentTime = 0;

            if (this.isMoving) {
                if (this.angle !== this._oldAngle) {
                    this._oldAngle = this.angle;
                    GameManager.getInstance().gamePlayerProxy.getPlayerController().playAction({
                        action: PlayerActionEnum.MOVE,
                        value: this.angle
                    });
                }
            } else {
                this.isMoving = false;
                if (GameManager.getInstance().gamePlayerProxy.getPlayerController().isMoving) {
                    GameManager.getInstance().gamePlayerProxy.getPlayerController().playAction({action: PlayerActionEnum.STOP_MOVE});
                }
            }
        }
    }
}
